<!-- eslint-disable no-console -->
<script setup>
import { nextTick, onMounted, ref, watch } from 'vue'
import G6 from '@antv/g6'

// 使用props定义
const props = defineProps({
  graphData: {
    type: Object,
    required: true,
  },
  curId: {
    type: Number,
    required: false,
  },
})

const colors = [
  '#BDD2FD',
  '#BDEFDB',
  '#C2C8D5',
  '#FBE5A2',
  '#F6C3B7',
  '#B6E3F5',
  '#D3C6EA',
  '#FFD8B8',
  '#AAD8D8',
  '#FFD6E7',
]
const strokes = [
  '#5B8FF9',
  '#5AD8A6',
  '#5D7092',
  '#F6BD16',
  '#E8684A',
  '#6DC8EC',
  '#9270CA',
  '#FF9D4D',
  '#269A99',
  '#FF99C3',
]

const graphContainer = ref(null)
const graph = ref(null)
const graphInitialized = ref(false) // 新增的标志，用来跟踪是否已初始化

// 初始化图表
function initGraph() {
  if (graphContainer.value && !graphInitialized.value) {
    console.log('图表层初始化Graph,curID是:')
    console.log(props.curId)
    // 配置tootip插件
    const tooltip = new G6.Tooltip({
      offsetX: 10,
      offsetY: 20,
      getContent(e) {
        if (e.item.getModel().cluster === '数值属性' && e.item.getModel().label !== '数值属性') {
          const outDiv = document.createElement('div')
          outDiv.style.width = '70px'
          outDiv.innerHTML = `
            <ul>
              <li>${e.item.getModel().properties.value || e.item.getModel().id}</li>
            </ul>`
          return outDiv
        }
        else {
          // TODO:对非数值属性节点，如何能不显示且不影响拖拽？
          const invisibleDiv = document.createElement('div')
          invisibleDiv.innerHTML = `
            <ul>
              <li>${e.item.getModel().cluster}</li>
            </ul>`
          return invisibleDiv
        }
      },
      itemTypes: ['node'],
    })
    // 配置G6
    graph.value = new G6.Graph({
      container: graphContainer.value, // 注意这里使用.value来访问ref的值
      width: graphContainer.value.offsetWidth,
      height: graphContainer.value.offsetHeight,
      modes: {
        default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 'click-select'
      },
      defaultNode: {
        size: 40,
        style: (node) => {
          if (node.highlight) {
            return {
              stroke: 'red',
              fill: '#C6E5FF',
              lineWidth: 3,
            }
          }
        },
      },
      defaultEdge: {
        style: {
          stroke: '#A3B1BF',
        },
      },
      nodeStateStyles: {
        hover: {
          fill: 'lightsteelblue',
        },
        click: {
          stroke: '#000',
          lineWidth: 5,
        },
      },
      layout: {
        type: 'force', // 指定为力导向布局
        gravity: 0.2, // 根据需要调整，增加此值以使节点更分散
        clustering: true,
        preventOverlap: true, // 防止节点重叠
        linkDistance: 100, // 边的长度
        fitView: true,
        fitViewPadding: [0, 0, 0, 0],
      },
      plugins: [tooltip], // 配置 Tooltip 插件
    })
    console.log(props.graphData)
    // 处理cluster分类
    const nodes = props.graphData.nodes
    const clusterMap = new Map()
    let clusterId = 0
    nodes.forEach((node) => {
      if (node.cluster && clusterMap.get(node.cluster) === undefined) {
        clusterMap.set(node.cluster, clusterId)
        clusterId++
      }
      const cid = clusterMap.get(node.cluster)
      if (!node.style)
        node.style = {}

      node.style.fill = colors[cid % colors.length]
      node.style.stroke = strokes[cid % strokes.length]
    })
    // 渲染
    graph.value.data(props.graphData)
    graph.value.render()
    graph.value.fitView()
    graph.value.refresh()
    graphInitialized.value = true // 设置标志
    updateGraph() // 确保图表用初始数据立即更新初始化
  }
}

// 更新图表
function updateGraph() {
  console.log('进入渲染层,curID是')
  console.log(props.curId)
  if (!graph.value)
    return // 如果图表未初始化，直接返回
  graph.value.changeData(props.graphData)
  updateHighlightedNodes()
  graph.value.fitView()
  graph.value.refresh()
  console.log('渲染层更新节点和边数据', props.graphData)
}

// 处理新增节点
function updateHighlightedNodes() {
  if (!graph.value)
    return

  const nodes = graph.value.getNodes()
  nodes.forEach((node) => {
    const model = node.getModel()
    if (model.highlight) {
      // 更新节点样式以反映高亮状态
      graph.value.updateItem(node, {
        style: {
          stroke: '#f00',
          lineWidth: 3,
        },
      })
    }
    else {
      // 确保非高亮节点有默认样式
      graph.value.updateItem(node, {
        style: {
          lineWidth: 1,
        },
      })
    }
    if (model.label === '患者') {
      model.fx = graphContainer.value.offsetWidth / 2
      model.fy = graphContainer.value.offsetHeight / 2
    }
  })
}

// 使用watchEffect进行更直接的方法，同时观察graphData和初始化标志
watch([() => props.graphData, graphInitialized], ([newGraphData, isInitialized], [oldGraphData, wasInitialized]) => {
  // 确保图表已初始化且数据确实发生了变化
  if (isInitialized && newGraphData !== oldGraphData)
    updateGraph()
}, { deep: true })

onMounted(() => {
  nextTick(() => {
    initGraph() // 确保DOM准备就绪
    // 点击节点
    graph.value.on('node:click', (evt) => {
      console.log('进入click处理')
      const nodeModel = evt.item.getModel()
      const logic = nodeModel.properties.logic
      console.log(logic)

      if (logic && logic.length > 0) { // 确实是有推理知识的节点
        // 先将所有当前是 click 状态的节点置为非 click 状态
        const clickNodes = graph.value.findAllByState('node', 'click')
        clickNodes.forEach((cn) => {
          graph.value.setItemState(cn, 'click', false)
        })
        const nodeItem = evt.item // 获取被点击的节点元素对象
        graph.value.setItemState(nodeItem, 'click', true) // 设置当前节点的 click 状态为 true

        // 移除之前所有知识点的高亮样式
        document.querySelectorAll('#reasonList tbody tr').forEach((element) => {
          element.classList.remove('highlight')
        })

        // 遍历logic数组，拿到其涉及到的所有index
        const targetIndex = []
        logic.forEach((element) => {
          targetIndex.push(element.index)
        })
        console.log(targetIndex)

        // 对表格中所有相应index的行修改样式
        const tableRows = document.querySelectorAll('#reasonList tbody tr')
        console.log('tableRows:')
        console.log(tableRows)
        tableRows.forEach((row, key) => {
          if (targetIndex.includes(key)) { // 确保索引合法
            // 在范围内的元素添加样式
            console.log(row)
            row.classList.add('highlight')
          }
        })
      }
    })

    // TODO: 监听空白处点击事件,依旧没调好
    graph.value.on('canvas:click', () => {
      console.log('检测到点击空白处')
      // 取消所有节点的选中状态
      const clickNodes = graph.value.findAllByState('node', 'click')
      clickNodes.forEach((node) => {
        graph.value.setItemState(node, 'click', false)
      })

      // 移除表格中所有行的高亮样式
      document.querySelectorAll('#reasonList tbody tr').forEach((element) => {
        element.classList.remove('highlight')
      })
    })
  })
})
</script>

<template>
  <div ref="graphContainer" class="g6" />
</template>

<style scoped>
.g6 {
  width: 100%;
  height: 100%;
  display: block;
  border: none;
  padding: none;
  box-sizing: border-box;
  background-color: rgba(244, 246, 246, 0.46);
}
.highlight {
    font-weight: bold;
    background-color: yellow;
}
</style>
